<script setup lang="ts">
import { onBeforeUnmount, onMounted, ref } from 'vue'

import {
  TreeManager,
  formatTechTreeImpl,
  type TechniqueTree,
  TechTreeNode,
  formatHandInTechniqueBomPrtCountImpl,
} from '../types/technique-bom'
import { ElButton, ElInput, type ElTree } from 'element-plus'
import type { TransData } from '../types/tree-type'
import { exportBomImpl } from '@/utils/export-utils'
import { storage } from '@/utils/storage'

onBeforeUnmount(() => {
  storage.set('treeValue', tree.value)
  storage.set('inputValue', techniqueName.value)
})

onMounted(() => {
  const treeValue = storage.get('treeValue')
  const inputValue = storage.get('inputValue')
  // if (treeValue != null && inputValue != null) {
  //   console.log('加载成功')
  tree.value = treeValue
  techniqueName.value = inputValue
  // }
})

const props = defineProps({
  productName: {
    type: String,
    default: '传动产品',
  },
})

const treeIn = ref<InstanceType<typeof ElTree>>()
const techniqueName = ref('')

const treeManager = new TreeManager()
const tree = ref<TechniqueTree>([])

const centerDialogVisible = ref(false)

const deletedTarget = ref<TechTreeNode>()

const emit = defineEmits(['hide', 'unhide', 'clear'])

const openDeleteConfirmDialog = (data: TechTreeNode) => {
  if (data.children?.length == 0) {
    deleteNodeInTechniqueBom(tree.value, data)
    return
  }
  centerDialogVisible.value = true
  deletedTarget.value = data
}

// 广播取消隐藏消息
const broadcastHiddenMessage = (data: TechTreeNode) => {
  const broadcastRecusively = (child: TechTreeNode) => {
    console.log(child)

    if (child.level == 3 && child.bomId != null) {
      emit('unhide', child.bomId)
      return
    }
    if (child.children?.length != 0) {
      child.children?.forEach((son) => {
        broadcastRecusively(son)
      })
    }
  }

  broadcastRecusively(data)
}

// 删除节点
const deleteNodeInTechniqueBom = (tree: TechniqueTree, target: TechTreeNode) => {
  const deleteInTheTree = (tree: TechniqueTree, aimId: string) => {
    for (let i = tree.length - 1; i >= 0; i--) {
      const treeNode = tree[i]
      if (treeNode.id == aimId) {
        tree.splice(i, 1)
        break
      }
      if (treeNode.children != null) {
        deleteInTheTree(treeNode.children, aimId)
      }
    }
  }

  const id = target.id
  if (id != null) {
    deleteInTheTree(tree, id)
    broadcastHiddenMessage(target)
  }
}

const confirmToDelete = () => {
  deleteNodeInTechniqueBom(tree.value, deletedTarget.value)
  centerDialogVisible.value = false
}

const createNewTechnique = (name: string) => {
  if (name.length > 0) {
    const newNode = treeManager.createLevel1Node(name)
    treeManager.addLevel1Node(tree.value, newNode)
  }
}

const createNewStep = (parent: TechTreeNode) => {
  const newNode = treeManager.createLevel2Node()
  treeManager.addLevel2Node(parent, newNode)
}

function drop_handler(event) {
  event.preventDefault()

  const single = event.dataTransfer.getData('single')
  const multi = event.dataTransfer.getData('multi')

  console.log(`single : ${single}; multi : ${multi}`)

  const inId = event.target.id

  const inNode = treeIn.value.getNode(inId)
  const nodeLevel = inNode.data.level

  if (nodeLevel != 2) {
    return
  }

  // 如果bom里没有多选的零件，说明没有多选拖放
  if (multi == '') {
    // 处理单零件拖放的情况
    // 获取拖出节点
    const singleTran = JSON.parse(single)

    const newNode = treeManager.createLevel3Node(singleTran.label, singleTran.id, singleTran.path)
    inNode.data.children.push(newNode)
    emit('hide', singleTran.id)
  } else {
    // 处理多零件拖放的情况
    const multiTran = JSON.parse(multi)

    multiTran.forEach((child: TransData) => {
      const newNode = treeManager.createLevel3Node(child.label, String(child.id), child.path)
      inNode.data.children.push(newNode)

      emit('hide', child.id)
      emit('clear')
    })
  }
}

const handInItsData = () => {
  const datapack = {
    treeValue: tree.value,
    inputValue: techniqueName.value,
  }
  return datapack
}

const recieveInputData = (inputData) => {
  const { treeValue, inputValue } = inputData

  tree.value = treeValue
  techniqueName.value = inputValue
}

const handInBackendData = () => {
  return formatTechTreeImpl(tree.value)
}

const handInTechniqueBomPrtCount = () => {
  return formatHandInTechniqueBomPrtCountImpl(tree.value)
}

defineExpose({
  handInItsData,
  recieveInputData,
  handInBackendData,
  handInTechniqueBomPrtCount,
})
</script>

<template>
  <div>
    <div style="display: flex">
      <el-input v-model="techniqueName" placeholder="输入工艺名称。。。" />
      <el-button
        style="margin: 0px 5px"
        type="success"
        size="default"
        @click="createNewTechnique(techniqueName)"
      >
        新建工艺
      </el-button>
    </div>
    <hr />
    <el-tree
      :data="tree"
      node-key="id"
      default-expand-all
      :expand-on-click-node="false"
      ref="treeIn"
    >
      <template #default="{ node, data }">
        <div>
          <ElInput v-model="data.label" @blur="data.edit = false" v-if="data.edit" size="small">
          </ElInput>
          <span :id="data.id" v-else @dblclick="data.edit = true" @drop="drop_handler">
            {{ node.label }}
          </span>
          <span class="right-align">
            <el-button
              size="small"
              type="success"
              v-if="data.level == 1"
              @click="createNewStep(data)"
              >新建工步</el-button
            >
            <el-button size="small" type="warning" @click="openDeleteConfirmDialog(data)"
              >移除
            </el-button>
          </span>
        </div>
      </template>
    </el-tree>

    <el-dialog v-model="centerDialogVisible" title="Warning" width="500" align-center>
      <span>删除的节点包含其他节点，删除它将连带全部删除，确定吗？</span>
      <div>>{{ deletedTarget?.label }}</div>
      <div v-for="node in deletedTarget.children">>{{ `  >${node.label}` }}</div>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="centerDialogVisible = false"> 取消 </el-button>
          <el-button type="primary" @click="confirmToDelete()"> 确定 </el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<style lang="css" scoped>
/* .container {
  display: flex;
} */

.right-align {
  position: absolute;
  right: 1px;
}
</style>
